package simulator.labyrinth;

import java.util.ArrayList;


public class Square {
	
	public enum SquareState {
		DISCOVERED, UNDISCOVERED, UNREACHABLE;
	}
	
	private SquareType type = SquareType.CROSSING;
	private ArrayList<Wall> walls= new ArrayList<Wall>();
	private ArrayList<BarCode> codes= new ArrayList<BarCode>();
	private ArrayList<Line> lines = new ArrayList<Line>();
	
	private SquareState state = SquareState.UNDISCOVERED;
	private boolean isFinish = false;
	private boolean isCheckPoint = false;

	public Square(){

	}
	
	public void setAsFinish() {
		isFinish = true;
	}
	
	public boolean isFinish() {
		return isFinish;
	}
	
	public void setAsCheckPoint() {
		isCheckPoint  = true;
	}
	
	public boolean isCheckPoint() {
		return isCheckPoint;
	}
	
	public void addWall(Wall wall) {
        synchronized(walls) {
            if (walls.contains(wall))
                return;

            walls.add(wall);
            switch(walls.size()){
            case 0:
            	type = SquareType.CROSSING;
				break;
            case 1:
            	type = SquareType.T_CROSSING;
				break;
			case 2:
				if(Double.compare(walls.get(0).getOrientation()%180, walls.get(1).getOrientation()%180)==0)
					type = SquareType.STRAIGHT;
				else
					type = SquareType.CORNER;
				break;
			case 3:
				type = SquareType.DEAD_END;
				break;
			case 4:
				state = SquareState.UNREACHABLE;
				type = SquareType.NONE;
				break;
			default:
				type = SquareType.NONE;
				break;
            }
            
        }
	}
	
	public void addBarCode(BarCode barCode) {
        synchronized(codes) {
            System.out.println("Lines of the barcode with position " + barCode.pos + " and orientation " + barCode.orientation + ":");
            for (Line l : barCode.getLines())
                System.out.println(l);
            codes.add(barCode);
        }
	}
	
	public ArrayList<Wall> getWalls() {
	    synchronized(walls) {
	        return walls;
	    }
	}
	
	public ArrayList<BarCode> getBarCodes(){
        synchronized(codes) {
            return codes;
        }
	}
	
	public ArrayList<Line> getLines() {
        synchronized(lines) {
        	ArrayList<Line> linesOfSquare = new ArrayList<Line>(lines);
        	for (BarCode b : getBarCodes()) {
        		linesOfSquare.addAll(b.getLines());
        	}
            return linesOfSquare;
        }
	}
	
	public void addLine(Line line) {
        synchronized(lines) {
            lines.add(line);
        }
	}
	
	public void setState(SquareState state) {
        synchronized(state) {
            this.state = state;
        }
	}
	
	public SquareState getState() {
        synchronized(state) {
            return state;
        }
	}
	public SquareType getType(){
		synchronized(walls){
		return type;
		}	
	}
}